package com.association.logging.aspect;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.TimeInterval;
import com.alibaba.fastjson.JSONObject;
import com.association.logging.aop.log.WebLog;
import com.association.logging.model.Log;
import com.association.logging.service.LogService;
import io.swagger.annotations.ApiOperation;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.HttpHeaders;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.time.LocalTime;
import java.util.Date;
import java.util.concurrent.TimeUnit;

/**
 * 日志切面
 *
 * @author liukai
 * @data 2018/8/7 15:50.
 */
@Aspect
@Component
public class WebLogAspect {
    @Resource
    private LogService logService;

    @Pointcut("@annotation(com.association.logging.aop.log.WebLog)")
    public void logPointCut() {}

    @Pointcut("@annotation(com.association.logging.aop.log.WebLog)")
    public void PointCut() {}




    @Around("logPointCut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        Long startTime = System.currentTimeMillis();

        Date beginTime=new Date();
        String result=null;
        int status=0;
        Object obj=null;
        try {
            obj = point.proceed();//放行请求的主进程并拿到返回值
            if(obj!=null) {
                result=JSONObject.toJSONString(obj);
            }
            status=0;
            return obj;
        } catch (Exception e) {
            result=e.getMessage();
            status=1;
            throw e;
        } finally {
            //执行消耗时间
            Long endTime = System.currentTimeMillis();
            long time=endTime - startTime;
            saveLog(point, beginTime, new Date(), result, status,time);
        }
    }

    private void saveLog(ProceedingJoinPoint joinPoint, Date beginTime, Date endTime, String result, int status,Long tiem) {

        Log log = new Log();
        try {
            MethodSignature signature = (MethodSignature) joinPoint.getSignature();
            Method method = signature.getMethod();
            WebLog annotation = method.getAnnotation(WebLog.class);
            int type=1;//注解类型
            // 也可以用来记录一些信息，比如获取请求的url和ip
            ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();

            HttpServletRequest request = attributes.getRequest();
            if (method.isAnnotationPresent(ApiOperation.class)) {
                ApiOperation apiOperation = method.getAnnotation(ApiOperation.class);
                System.out.println("//接口描述\n"+apiOperation.value());
            }
            if(status==1){
                log.setExceptionDetail(result);//报错信息
                log.setType(1);
            }
            log.setBrowser(request.getMethod());//得到请求URL地址时使用的方法


            log.setDescription(annotation.value());
            log.setLogType(status==0?"INFO":"ERROR");//执行结果
            log.setMethod(request.getRequestURL().toString());
            log.setTime(tiem);//消耗的时间
            if(joinPoint.getArgs()!=null) {
                try {
                    //返回的结果
                    log.setParams(result);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            log.setRequestIp(request.getRemoteAddr());
            log.setUserName(request.getHeader("userName"));
            log.setUid(Long.parseLong(request.getHeader("userId")));

            log.setAddress(request.getRemoteAddr().equals("127.0.0.1")?"本地链接":"局域网");

        } catch (Exception e) {
            e.printStackTrace();
        }

        new Thread() {
            @Override
            public void run() {
                try {
                    logService.record(log);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }.start();
    }
}